
#ifndef __EDNN_H__
#define __EDNN_H__



#include "ednn_config.h"
#include "ednn_def.h"
#include "ednn_utils.h"
#include "ednn_layers.h"
#include "ednn_port.h"


ednn_size_t ednn_align(ednn_size_t value, ednn_size_t alignment);
ednn_ret ednn_layer_add(struct ednn_model *model, struct ednn_layer *layer);
ednn_ret ednn_model_run(struct ednn_model *model, struct ednn_tensor *input);
struct ednn_model *ednn_model_create(const char *name);
ednn_ret ednn_model_compile(struct ednn_model *model);
ednn_ret ednn_model_weights_load_frombuff(struct ednn_model *model, 
    ednn_uint8_t *buff);
void ednn_model_summary(struct ednn_model *model);
int ednn_tensor_shape_compare(struct ednn_tensor *t1, struct ednn_tensor *t2);
struct ednn_tensor *ednn_tensor_create(ednn_shape_t *dim, ednn_uint32_t ndim);
ednn_size_t ednn_tensor_get_nch(struct ednn_tensor *tensor);
ednn_size_t ednn_tensor_size(struct ednn_tensor *tensor);

int ednn_strb_build(ednn_strb_t *bpr, const char *fmt, ...);
void ednn_strb_setup(ednn_strb_t *s, char *buff, int len);

#define ednn_strb_none()				{EDNN_NULL, EDNN_NULL, 0, 0}

#define ednn_strb_init(s, max)			{(s), (s), max, ednn_strlen(s)}

#define ednn_strb_string(p, s)			(ednn_strb_build(&p, "%s", s))
#define ednn_strb_number(p, n)			(ednn_strb_build(&p, "%d", n))
#define ednn_strb_hex(p, h)				(ednn_strb_build(&p, "%x", h))
#define ednn_strb_format(p, fmt, ...)	(ednn_strb_build(&p, fmt, ##__VA_ARGS__))


void ednn_assert_set_hook(void (*hook)(const char *, const char *, ednn_size_t));
void ednn_assert_handler(const char *ex_string, const char *func, ednn_size_t line);
#define ednn_assert(ex)                                                     \
if (!(ex))                                                               	\
{                                                                         	\
    ednn_assert_handler(#ex, __FUNCTION__, __LINE__);                       \
}

/**
 * @addtogroup Log
 */
void ednn_log(ednn_uint8_t level, const char *func, int line, const char *format, ...);

#define ednn_debug(...)      ednn_log(EDNN_LOG_DEBUG,  __func__, __LINE__, __VA_ARGS__)
#define ednn_info(...)       ednn_log(EDNN_LOG_INFO,   __func__, __LINE__, __VA_ARGS__)
#define ednn_notice(...)     ednn_log(EDNN_LOG_NOTICE, __func__, __LINE__, __VA_ARGS__)
#define ednn_warn(...)       ednn_log(EDNN_LOG_WARN,   __func__, __LINE__, __VA_ARGS__)
#define ednn_err(...)        ednn_log(EDNN_LOG_ERR,    __func__, __LINE__, __VA_ARGS__)
/* @end of Log */

void *ednn_mem_zalloc(ednn_size_t size);
ednn_size_t ednn_mem_used(void);
void ednn_mem_free(void *p);

void ednn_list_append(ednn_list_t *n, ednn_list_t *existing);
void ednn_list_init(ednn_list_t *list);

char *ednn_strncpy(char *dst, const char *src, ednn_size_t n);

ednn_uint32_t ednn_ms_get(void);
ednn_uint64_t ednn_us_get(void);


#endif /* __EDNN_H__ */
